﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json.Linq;

namespace LdCms.Web.Controllers.API.Member.V1
{
    using LdCms.Common.Enum;
    using LdCms.Common.Extension;
    using LdCms.Common.Net;
    using LdCms.Common.Security;
    using LdCms.Common.Time;
    using LdCms.Common.Token;
    using LdCms.Common.Utility;
    using LdCms.EF.DbModels;
    /// <summary>
    /// 会员注册接口：
    ///     1、会员自动生成
    ///        URL：member/create?uuid=uuid
    ///        POST：{"pid":"","openid":"123456","account":"6666298","name":"","phone":"18666376363","password":"123456","typeid":1}
    ///     2、会员注册
    ///        URL：member/register?uuid=uuid
    ///        POST：{"account":"6666298","name":"","phone":"18666376363","password":"123456","typeid":1,"sms_pid":"","send_id":"","code":"123456"}
    ///     3、会员登录
    ///        URL：member/login?uuid=uuid
    ///        POST：{"account":"18666376363","password":"123456"}
    ///     4、刷新访问令牌
    ///        URL：member/token/refresh?uuid=uuid
    ///        POST：{"refresh_token":"12233456498"}
    ///     5、验证访问令牌
    ///        GET：member/token/verify?access_token=access_token
    ///     6、验证会员注册手机号是否正确
    ///        URL：member/phone/verify?access_token=access_token
    ///        POST：{"phone":"12233456498"}
    ///     7、验证用户名是否注册
    ///        URL：member/register/username/verify?uuid=uuid
    ///        POST：{"user_name":"12233456498"}
    ///     8、验证手机号是否注册
    ///        URL：member/register/phone/verify?uuid=uuid
    ///        POST：{"phone":"12233456498"}
    /// 
    /// 
    /// </summary>
    public partial class MemberController : BaseApiController
    {
        /// <summary>
        /// 会员生成
        /// </summary>
        /// <param name="uuid"></param>
        /// <param name="fromValue">{"pid":"","openid":"123456","account":"6666298","name":"","phone":"18666376363","password":"123456","typeid":1}</param>
        /// <returns></returns>
        [HttpPost]
        [ActionName("create")]
        public IActionResult Create(string uuid, [FromBody]JObject fromValue)
        {
            long logId = 0;
            try
            {
                logId = BaseApiManager.SaveLogs(uuid, fromValue);
                bool isParams = IsCreateParams(fromValue);

                int systemId = InterfaceAccount.SystemID;
                string companyId = InterfaceAccount.CompanyID;
                string memberId = PrimaryKeyHelper.MakePrimaryKey(PrimaryKeyHelper.PrimaryKeyType.MemberAccount);
                string platformId = GetJObjectValue(fromValue, "pid");
                string openId = GetJObjectValue(fromValue, "openid");
                string userName = GetJObjectValue(fromValue, "account");
                string name = GetJObjectValue(fromValue, "name");
                string phone = GetJObjectValue(fromValue, "phone");
                string password = GetJObjectValue(fromValue, "password");
                string typeId = GetJObjectValue(fromValue, "typeid");
                string ipAddress = Net.Ip;

                if (string.IsNullOrWhiteSpace(platformId))
                    return Error(logId, "pid not empty！");
                if (string.IsNullOrWhiteSpace(openId))
                    return Error(logId, "openid not empty！");

                if (string.IsNullOrWhiteSpace(userName))
                    userName = memberId;
                if (string.IsNullOrWhiteSpace(phone))
                    phone = memberId.Left(11);
                if (string.IsNullOrWhiteSpace(userName))
                    password = memberId;
                int classId = Utility.IsNum(typeId, 1);
                string className = EnumHelper.GetName<ParamEnum.MemberType>(classId);
                var result = AccountService.SaveAccountRegisterPro(systemId, companyId, memberId, classId, className, userName, AlgorithmHelper.MD5(password),name, phone, ipAddress);
                if (result)
                {
                    int pointClassId = (int)ParamEnum.MemberPointClass.新人;
                    int pointTypeId = (int)ParamEnum.MemberPointType.新增;
                    bool pointResult = AddPointRecordPro(companyId, memberId, pointClassId, pointTypeId, "新用户增送积分！");
                    //bool bind = UserMemberService.SaveUserMember(new Ld_WeChat_UserMember()
                    //{
                    //    SystemID = systemId,
                    //    CompanyID = companyId,
                    //    PlatformID = platformId,
                    //    OpenID = openId,
                    //    MemberID = memberId
                    //});
                    if (result)
                        return Success(logId, "ok");
                    else
                        return Error(logId, "fail");
                }
                else
                {
                    return Error(logId, "fail！");
                }
            }
            catch (Exception ex)
            {
                return Error(logId, ex.Message);
            }
        }
        /// <summary>
        /// 会员注册
        /// </summary>
        /// <param name="uuid"></param>
        /// <param name="fromValue">{"account":"6666298","name":"","phone":"18666376363","password":"123456","typeid":1,"sms_pid":"","send_id":"","code":"123456"}</param>
        /// <returns></returns>
        [HttpPost]
        [ActionName("register")]
        public IActionResult Register(string uuid, [FromBody]JObject fromValue)
        {
            long logId = 0;
            try
            {
                logId = BaseApiManager.SaveLogs(uuid, fromValue);
                bool isParams = IsRegisterParams(fromValue);
                string companyId = InterfaceAccount.CompanyID;
                string memberId = PrimaryKeyHelper.MakePrimaryKey(PrimaryKeyHelper.PrimaryKeyType.MemberAccount);
                string userName = GetJObjectValue(fromValue, "account");
                string name = GetJObjectValue(fromValue, "name");
                string phone = GetJObjectValue(fromValue, "phone");
                string password = GetJObjectValue(fromValue, "password");
                string typeId = GetJObjectValue(fromValue, "typeid");
                int classId = Utility.IsNum(typeId, 1);
                string className = EnumHelper.GetName<ParamEnum.MemberType>(classId);
                string ipAddress = Net.Ip;

                if (!Utility.IsAccount(userName)) { return Error(logId, "用户只能由字母、数字组成！"); }
                if (!Utility.IsMobilePhone(phone)) { return Error(logId, "手机号码格式不正确！"); }

                var result = AccountService.SaveAccountRegisterPro(SystemID, companyId, memberId, classId, className, userName, AlgorithmHelper.MD5(password), name, phone, ipAddress);
                if (result)
                {
                    int pointClassId = (int)ParamEnum.MemberPointClass.新人;
                    int pointTypeId = (int)ParamEnum.MemberPointType.新增;
                    bool pointResult = AddPointRecordPro(companyId, memberId, pointClassId, pointTypeId, "新用户增送积分！");
                    return Success(logId, "ok");
                }
                else
                {
                    return Error(logId, "fail");
                }
            }
            catch (Exception ex)
            {
                return Error(logId, ex.Message);
            }
        }
        /// <summary>
        /// 会员登录
        /// </summary>
        /// <param name="uuid"></param>
        /// <param name="fromValue">{"account":"18666376363","password":"123456"}</param>
        /// <returns></returns>
        [HttpPost]
        [ActionName("login")]
        public IActionResult Login(string uuid, [FromBody]JObject fromValue)
        {
            long logId = 0;
            try
            {
                logId = BaseApiManager.SaveLogs(uuid, fromValue);
                bool isParams = IsLoginParams(fromValue);
                string companyId = InterfaceAccount.CompanyID;
                string account = GetJObjectValue(fromValue, "account");
                string password = GetJObjectValue(fromValue, "password");
                var result = AccountService.VerifyAccountLoginPro(SystemID, companyId, account, AlgorithmHelper.MD5(password));
                if (result)
                {
                    var entityMember = AccountService.GetAccountByUserName(SystemID, companyId, account);
                    string memberId = entityMember.MemberID;
                    var tokenService = new TokenHelper();
                    string token = tokenService.GetToken();
                    string refreshToken = tokenService.GetToken();
                    int expiresIn = AccessTokenExpiresIn;
                    string ipAddress = Net.Ip;
                    int createTimestamp = TimeHelper.GetUnixTimestampTen();
                    var createResult = AccountAccessTokenService.SaveAccessTokenPro(token, refreshToken, SystemID, companyId, memberId, uuid, "", expiresIn, RefreshTokenExpiresIn, ipAddress, createTimestamp);
                    if (createResult)
                    {
                        int pointClassId = (int)ParamEnum.MemberPointClass.登录;
                        int pointTypeId = (int)ParamEnum.MemberPointType.新增;
                        bool pointResult = AddPointRecordPro(companyId, memberId, pointClassId, pointTypeId, "用户登录获取积分！");
                        bool saveLoginLogResult = SaveLoginLogs(memberId, account, entityMember.NickName, true);
                        return Result(logId, new
                        {
                            access_token = token,
                            expiresin = expiresIn,
                            refresh_token = refreshToken,
                            memberid = memberId,
                            scope = "scope"
                        });
                    }
                    return Error(logId, "fail");
                }
                return Error(logId, "login fail！");
            }
            catch (Exception ex)
            {
                return Error(logId, ex.Message);
            }
        }
        /// <summary>
        /// 刷新access_token
        /// </summary>
        /// <param name="uuid"></param>
        /// <param name="fromValue">{"refresh_token":"12233456498"}</param>
        /// <returns></returns>
        [HttpPost]
        [ActionName("token/refresh")]
        public IActionResult RefreshToken(string uuid, [FromBody]JObject fromValue)
        {
            long logId = 0;
            try
            {
                logId = BaseApiManager.SaveLogs(uuid);
                bool isParams = IsRefreshTokenParams(fromValue);
                string fRefreshToken = GetJObjectValue(fromValue, "refresh_token");
                if (string.IsNullOrWhiteSpace(fRefreshToken)) { return Error(logId, "refresh token not empty！"); }
                var tokenService = new TokenHelper();
                string token = tokenService.GetToken();
                string refreshToken = tokenService.GetToken();
                int expiresIn = AccessTokenExpiresIn;
                int refreshTokenExpiresIn = RefreshTokenExpiresIn;
                string ipAddress = Net.Ip;
                int createTimestamp = TimeHelper.GetUnixTimestampTen();
                var createResult = AccountAccessTokenService.SaveRefreshTokenPro(fRefreshToken, token, refreshToken, expiresIn, refreshTokenExpiresIn, ipAddress, createTimestamp);
                if (createResult)
                {
                    var entityMember = AccountAccessTokenService.GetAccessToken(token);
                    return Result(logId, new
                    {
                        access_token = token,
                        expiresin = expiresIn,
                        refresh_token = refreshToken,
                        memberid = entityMember.MemberID,
                        scope = "scope"
                    });
                }
                return Error(logId, "fail");
            }
            catch (Exception ex)
            {
                return Error(logId, ex.Message);
            }
        }
        /// <summary>
        /// 验证Token
        /// </summary>
        /// <param name="access_token"></param>
        /// <returns></returns>
        [HttpGet]
        [ActionName("token/verify")]
        public IActionResult VerifyToken(string access_token)
        {
            long logId = 0;
            try
            {
                logId = BaseApiManager.SaveLogs(access_token);
                if (string.IsNullOrWhiteSpace(access_token))
                    return Error(logId, "token not empty！");
                int timestamp = TimeHelper.GetUnixTimestampTen();
                var result = AccountAccessTokenService.VerifyAccessTokenPro(access_token, timestamp);
                if (result)
                    return Success(logId, "ok");
                else
                    return Error(logId, "fail");
            }
            catch (Exception ex)
            {
                return Error(logId, ex.Message);
            }
        }
        /// <summary>
        /// 验证手机号码
        /// </summary>
        /// <param name="access_token"></param>
        /// <param name="fromValue">{"phone":""}</param>
        /// <returns></returns>
        [HttpPost]
        [ActionName("phone/verify")]
        public IActionResult VerifyPhone(string access_token, [FromBody]JObject fromValue)
        {
            long logId = 0;
            try
            {
                logId = BaseApiManager.SaveLogs(access_token);
                bool isParams = IsVerifyPhoneParams(fromValue);
                string phone = GetJObjectValue(fromValue, "phone");
                if (MemberAccount.Phone==phone)
                    return Success(logId, "ok");
                else
                    return Error(logId, "fail");
            }
            catch (Exception ex)
            {
                return Error(logId, ex.Message);
            }
        }
        /// <summary>
        /// 验证会户名是否注册
        /// </summary>
        /// <param name="access_token"></param>
        /// <param name="fromValue">{"user_name":""}</param>
        /// <returns></returns>
        [HttpPost]
        [ActionName("register/username/verify")]
        public IActionResult VerifyRegisterUserName(string uuid, [FromBody]JObject fromValue)
        {
            long logId = 0;
            try
            {
                logId = BaseApiManager.SaveLogs(uuid);
                bool isParams = IsVerifyUserNameParams(fromValue);
                string userName = GetJObjectValue(fromValue, "user_name");
                int systemId = InterfaceAccount.SystemID;
                string companyId = InterfaceAccount.CompanyID;
                var entity = AccountService.GetAccountByUserName(systemId, companyId, userName);
                if (entity != null)
                    return Success(logId, "ok");
                else
                    return Error(logId, "fail");
            }
            catch (Exception ex)
            {
                return Error(logId, ex.Message);
            }
        }
        /// <summary>
        /// 验证手机号码
        /// </summary>
        /// <param name="access_token"></param>
        /// <param name="fromValue">{"phone":""}</param>
        /// <returns></returns>
        [HttpPost]
        [ActionName("register/phone/verify")]
        public IActionResult VerifyRegisterPhone(string uuid, [FromBody]JObject fromValue)
        {
            long logId = 0;
            try
            {
                logId = BaseApiManager.SaveLogs(uuid);
                bool isParams = IsVerifyPhoneParams(fromValue);
                string phone = GetJObjectValue(fromValue, "phone");
                int systemId = InterfaceAccount.SystemID;
                string companyId = InterfaceAccount.CompanyID;
                var entity = AccountService.GetAccountByPhone(systemId, companyId, phone);
                if (entity != null)
                    return Success(logId, "ok");
                else
                    return Error(logId, "fail");
            }
            catch (Exception ex)
            {
                return Error(logId, ex.Message);
            }
        }

        #region 私有化方法
        private bool IsLoginParams(JObject formValue)
        {
            try
            {
                if (formValue == null)
                    throw new Exception("params not empty！");
                if (formValue.Property("account") == null)
                    throw new Exception("lack account params！");
                if (formValue.Property("password") == null)
                    throw new Exception("lack password params！");
                return true;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }
        private bool IsRegisterParams(JObject formValue)
        {
            try
            {
                if (formValue == null)
                    throw new Exception("params not empty！");
                if (formValue.Property("account") == null)
                    throw new Exception("lack account params！");
                if (formValue.Property("phone") == null)
                    throw new Exception("lack phone params！");
                if (formValue.Property("password") == null)
                    throw new Exception("lack password params！");
                return true;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }
        private bool IsCreateParams(JObject formValue)
        {
            try
            {
                if (formValue == null)
                    throw new Exception("params not empty！");
                if (formValue.Property("pid") == null)
                    throw new Exception("lack pid params！");
                if (formValue.Property("openid") == null)
                    throw new Exception("lack openid params！");
                return true;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }
        private bool IsRefreshTokenParams(JObject formValue)
        {
            try
            {
                if (formValue == null)
                    throw new Exception("params not empty！");
                if (formValue.Property("refresh_token") == null)
                    throw new Exception("lack refresh_token params！");
                return true;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }
        private bool IsVerifyPhoneParams(JObject formValue)
        {
            try
            {
                if (formValue == null)
                    throw new Exception("params not empty！");
                if (formValue.Property("phone") == null)
                    throw new Exception("lack phone params！");
                return true;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }
        private bool IsVerifyUserNameParams(JObject formValue)
        {
            try
            {
                if (formValue == null)
                    throw new Exception("params not empty！");
                if (formValue.Property("user_name") == null)
                    throw new Exception("lack phone params！");
                return true;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }
        #endregion


    }
}